package com.g001.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;

import com.g001.enums.ProxBlockType;
import com.g001.model.BorderBlock;
import com.g001.model.GameBlock;
import com.g001.model.IBlock;

public class BlockUtils {
	
	
	public static List<IBlock> copyWithoutRendition(List<IBlock> blocks) throws SlickException{
		// Ori / dest
		Map<IBlock,IBlock> copyHas = new HashMap<IBlock,IBlock>(blocks.size()); // same size - it is a copy - speed up copy
		for(IBlock blockOri : blocks){
			copyHas.put(blockOri, copyWithoutRendition(blockOri));
		}
		// now we attach the proxiblocks
		for(IBlock blockOri : blocks){
			attachProxyBlocks(blockOri, copyHas.get(blockOri), copyHas.values());
		}
		return  new ArrayList<IBlock>(copyHas.values());		
		
	} 
	
	private static void attachProxyBlocks(IBlock blockOri, IBlock blockDest, Collection<IBlock> blocks){
		IBlock px = null;
		if(blockOri!=null && blockDest!=null) {
			for(ProxBlockType pbt : blockOri.getProxiBlocks().keySet()){
				px = blockOri.getProxyBlock(pbt);
				if(px!=null){
					for(IBlock b : blocks){
						if(b.getId().compareTo(px.getId())==0 ) {
							blockDest.setProxyBlock(pbt, b);
							break;
						}
					}
				}
			}
		}
	}
	
	private static IBlock copyWithoutRendition(IBlock block) throws SlickException{
		IBlock copy = null;
		if(block instanceof GameBlock) {
			copy = new GameBlock(block.getBlockType(), block.i, block.j, new Vector2f(0,0), null);
		} else if(block instanceof BorderBlock) {
			copy = new BorderBlock(block.i, block.j, new Vector2f(0,0));
		}
		copy.setId(block.getId());
		copy.x = block.x;
		copy.y = block.y;
		return copy;
	}
	
	
	public static IBlock findBlock(UUID uuid, List<IBlock> blocks) {
		IBlock block = null;
		for(IBlock b : blocks) {
			if(b.getId().compareTo(uuid)==0) return b;
		}
		return block;
	}

}
